/**
 * @file 浏览记录服务
 * @description 提供浏览记录的 CRUD 操作和查询功能
 * @author 黄敏
 * @version 1.0.0
 * @since 2025-09-19
 */

import Realm from 'realm'
import type {
  CreateBrowsingHistoryInput,
  DatabaseResult,
  QueryBrowsingHistoryParams,
  UpdateBrowsingHistoryInput
} from '../types'
import { BrowsingHistoryModel } from '#/database/models/browsing-history.model'
import { getDatabase } from '#/database'

/**
 * 浏览记录服务类
 */
export class BrowsingHistoryService {
  private static instance: BrowsingHistoryService | null = null

  /**
   * 获取服务实例（单例模式）
   */
  static getInstance(): BrowsingHistoryService {
    if (!this.instance) {
      this.instance = new BrowsingHistoryService()
    }
    return this.instance
  }

  /**
   * 私有构造函数
   */
  private constructor() {
    // 私有构造函数，确保单例模式
  }

  /**
   * 添加浏览记录
   * @param realm Realm 实例
   * @returns 操作结果
   */
  private getNextLegacyId(realm: Realm): number {
    const withIds = realm
      .objects('BrowsingHistory')
      .filtered('id != nil') as unknown as BrowsingHistoryModel[]
    if (withIds.length === 0) return 1
    const max = withIds.reduce((m, r) => (r.id && r.id > m ? r.id : m), 0)
    return (max || 0) + 1
  }

  async addRecord(
    input: CreateBrowsingHistoryInput
  ): Promise<DatabaseResult<BrowsingHistoryModel>> {
    try {
      const realm = getDatabase()
      const now = new Date()

      let newRecord: BrowsingHistoryModel

      realm.write(() => {
        const nextId = this.getNextLegacyId(realm)
        newRecord = realm.create('BrowsingHistory', {
          _id: new Realm.BSON.ObjectId(),
          id: nextId,
          url: input.url,
          title: input.title || null,
          favicon_url: input.favicon_url || null,
          visit_time: input.visit_time || now,
          visit_count: input.visit_count || 1,
          created_at: now,
          updated_at: now
        }) as BrowsingHistoryModel
      })

      // console.log(`✅ 浏览记录添加成功: ${input.url}`)

      return {
        success: true,
        data: newRecord!
      }
    } catch (error) {
      console.error('❌ 添加浏览记录失败:', error)
      return {
        success: false,
        error: `添加浏览记录失败: ${error}`
      }
    }
  }

  /**
   * 添加或更新浏览记录
   * 如果 URL 已存在，则增加访问次数并更新信息；否则创建新记录
   * @param input 浏览记录输入数据
   * @returns 操作结果
   */
  async addOrUpdateRecord(
    input: CreateBrowsingHistoryInput
  ): Promise<DatabaseResult<BrowsingHistoryModel>> {
    try {
      const realm = getDatabase()

      // 检查是否已存在该 URL 的记录
      const existingRecord = realm
        .objects('BrowsingHistory')
        .filtered('url == $0', input.url)[0] as unknown as BrowsingHistoryModel | undefined

      if (existingRecord) {
        // 如果距离上次增加访问次数超过5分钟，则增加访问次数并更新访问时间
        let visit_count = existingRecord.visit_count
        let visit_time = existingRecord.visit_time
        const timeDiff = Date.now() - existingRecord.visit_time.getTime()

        if (timeDiff > 300_000) {
          // 5分钟 = 300000毫秒
          console.log(
            `距离上次访问: ${timeDiff}ms (${Math.round(timeDiff / 1000)}秒)，增加访问次数`
          )
          visit_count = existingRecord.visit_count + 1
          visit_time = new Date() // 更新最后一次增加访问次数的时间
        } else {
          console.log(
            `距离上次访问: ${timeDiff}ms (${Math.round(timeDiff / 1000)}秒)，不增加访问次数`
          )
        }

        // 更新现有记录
        realm.write(() => {
          existingRecord.title = input.title || existingRecord.title
          existingRecord.favicon_url = input.favicon_url || existingRecord.favicon_url
          existingRecord.visit_count = visit_count
          existingRecord.visit_time = visit_time
          existingRecord.updated_at = new Date()
        })

        // console.log(`✅ 浏览记录更新成功: ${input.url}`)
        return {
          success: true,
          data: existingRecord
        }
      } else {
        // 创建新记录
        return await this.addRecord(input)
      }
    } catch (error) {
      console.error('❌ 添加或更新浏览记录失败:', error)
      return {
        success: false,
        error: `添加或更新浏览记录失败: ${error}`
      }
    }
  }

  /**
   * 更新浏览记录
   * @param id 记录ID
   * @param input 更新数据
   * @returns 操作结果
   */
  async updateRecord(
    id: string,
    input: Omit<UpdateBrowsingHistoryInput, 'id'>
  ): Promise<DatabaseResult<BrowsingHistoryModel>> {
    try {
      console.log(`准备写入浏览记录`)

      const realm = getDatabase()
      const objectId = new Realm.BSON.ObjectId(id)
      const record = realm.objectForPrimaryKey(
        BrowsingHistoryModel,
        objectId
      ) as BrowsingHistoryModel

      if (!record) {
        return {
          success: false,
          error: '记录不存在'
        }
      }

      realm.write(() => {
        if (input.title !== undefined) record.title = input.title
        if (input.favicon_url !== undefined) record.favicon_url = input.favicon_url
        if (input.visit_time !== undefined) record.visit_time = input.visit_time
        if (input.visit_count !== undefined) record.visit_count = input.visit_count
        record.updated_at = new Date()
      })

      console.log(`✅ 浏览记录更新成功: ${record.url}`)
      return {
        success: true,
        data: record
      }
    } catch (error) {
      console.error('❌ 更新浏览记录失败:', error)
      return {
        success: false,
        error: `更新浏览记录失败: ${error}`
      }
    }
  }

  /**
   * 删除浏览记录
   * @param id 记录ID
   * @returns 操作结果
   */
  async deleteRecord(id: string): Promise<DatabaseResult<void>> {
    try {
      const realm = getDatabase()
      const objectId = new Realm.BSON.ObjectId(id)
      const record = realm.objectForPrimaryKey(
        BrowsingHistoryModel,
        objectId
      ) as BrowsingHistoryModel

      if (!record) {
        return {
          success: false,
          error: '记录不存在'
        }
      }

      realm.write(() => {
        realm.delete(record)
      })

      console.log(`✅ 浏览记录删除成功: ID ${id}`)
      return {
        success: true
      }
    } catch (error) {
      console.error('❌ 删除浏览记录失败:', error)
      return {
        success: false,
        error: `删除浏览记录失败: ${error}`
      }
    }
  }

  /**
   * 根据ID查找浏览记录
   * @param id 记录ID
   * @returns 查找结果
   */
  async findById(id: string): Promise<DatabaseResult<BrowsingHistoryModel | null>> {
    try {
      const realm = getDatabase()
      const objectId = new Realm.BSON.ObjectId(id)
      const record = realm.objectForPrimaryKey(
        BrowsingHistoryModel,
        objectId
      ) as BrowsingHistoryModel | null

      return {
        success: true,
        data: record
      }
    } catch (error) {
      console.error('❌ 根据ID查找浏览记录失败:', error)
      return {
        success: false,
        error: `根据ID查找浏览记录失败: ${error}`
      }
    }
  }

  /**
   * 根据URL查找浏览记录
   * @param url URL地址
   * @returns 查找结果
   */
  async findByUrl(url: string): Promise<DatabaseResult<BrowsingHistoryModel | null>> {
    try {
      const realm = getDatabase()
      const records = realm.objects('BrowsingHistory').filtered('url == $0', url)
      const record = records.length > 0 ? (records[0] as unknown as BrowsingHistoryModel) : null

      return {
        success: true,
        data: record
      }
    } catch (error) {
      console.error('❌ 根据URL查找浏览记录失败:', error)
      return {
        success: false,
        error: `根据URL查找浏览记录失败: ${error}`
      }
    }
  }

  /**
   * 查询浏览记录
   * @param params 查询参数
   * @returns 查询结果
   */
  async queryRecords(
    params: QueryBrowsingHistoryParams = {}
  ): Promise<DatabaseResult<BrowsingHistoryModel[]>> {
    try {
      const realm = getDatabase()
      let results = realm.objects('BrowsingHistory')

      // 构建查询条件
      const filters: string[] = []

      if (params.url) {
        filters.push(`url CONTAINS[c] "${params.url}"`)
      }

      if (params.title) {
        filters.push(`title CONTAINS[c] "${params.title}"`)
      }

      if (params.startTime) {
        filters.push(`visit_time >= $0`)
        results = results.filtered(`visit_time >= $0`, params.startTime)
      }

      if (params.endTime) {
        filters.push(`visit_time <= $0`)
        results = results.filtered(`visit_time <= $0`, params.endTime)
      }

      // 应用过滤器
      if (filters.length > 0) {
        const filterString = filters.join(' AND ')
        results = results.filtered(filterString)
      }

      // 排序
      const sortBy = params.sortBy || 'visit_time'
      const sortOrder = params.sortOrder === 'asc'
      results = results.sorted(sortBy, sortOrder)

      // 分页
      const offset = params.offset || 0
      const limit = params.limit || 100
      const slicedResults = Array.from(
        results.slice(offset, offset + limit)
      ) as unknown as BrowsingHistoryModel[]

      console.log(`✅ 查询浏览记录成功，返回 ${slicedResults.length} 条记录`)

      return {
        success: true,
        data: slicedResults,
        count: results.length
      }
    } catch (error) {
      console.error('❌ 查询浏览记录失败:', error)
      return {
        success: false,
        error: `查询浏览记录失败: ${error}`,
        data: []
      }
    }
  }

  /**
   * 获取最近访问的记录
   * @param limit 返回记录数量
   * @returns 查询结果
   */
  async getRecentRecords(limit = 20): Promise<DatabaseResult<BrowsingHistoryModel[]>> {
    return await this.queryRecords({
      limit,
      sortBy: 'visit_time',
      sortOrder: 'desc'
    })
  }

  /**
   * 获取访问次数最多的记录
   * @param limit 返回记录数量
   * @returns 查询结果
   */
  async getMostVisitedRecords(limit = 20): Promise<DatabaseResult<BrowsingHistoryModel[]>> {
    return await this.queryRecords({
      limit,
      sortBy: 'visit_count',
      sortOrder: 'desc'
    })
  }

  /**
   * 搜索浏览记录
   * @param keyword 搜索关键词
   * @param limit 返回记录数量
   * @returns 查询结果
   */
  async searchRecords(
    keyword: string,
    limit = 50
  ): Promise<DatabaseResult<BrowsingHistoryModel[]>> {
    try {
      const realm = getDatabase()
      const results = realm
        .objects('BrowsingHistory')
        .filtered('url CONTAINS[c] $0 OR title CONTAINS[c] $0', keyword)
        .sorted([
          ['visit_count', true],
          ['visit_time', true]
        ])
        .slice(0, limit)

      const records = Array.from(results) as unknown as BrowsingHistoryModel[]

      return {
        success: true,
        data: records
      }
    } catch (error) {
      console.error('❌ 搜索浏览记录失败:', error)
      return {
        success: false,
        error: `搜索浏览记录失败: ${error}`,
        data: []
      }
    }
  }

  /**
   * 获取记录总数
   * @returns 记录总数
   */
  async getRecordCount(): Promise<DatabaseResult<number>> {
    try {
      const realm = getDatabase()
      const count = realm.objects('BrowsingHistory').length

      return {
        success: true,
        data: count
      }
    } catch (error) {
      console.error('❌ 获取记录总数失败:', error)
      return {
        success: false,
        error: `获取记录总数失败: ${error}`,
        data: 0
      }
    }
  }

  /**
   * 清空所有浏览记录
   * @returns 操作结果
   */
  async clearAllRecords(): Promise<DatabaseResult<void>> {
    try {
      const realm = getDatabase()
      const allRecords = realm.objects('BrowsingHistory')
      const count = allRecords.length

      realm.write(() => {
        realm.delete(allRecords)
      })

      console.log(`✅ 清空浏览记录成功，删除了 ${count} 条记录`)

      return {
        success: true,
        count
      }
    } catch (error) {
      console.error('❌ 清空浏览记录失败:', error)
      return {
        success: false,
        error: `清空浏览记录失败: ${error}`
      }
    }
  }

  /**
   * 批量删除记录
   * @param ids 要删除的记录ID数组
   * @returns 操作结果
   */
  async deleteRecords(ids: string[]): Promise<DatabaseResult<void>> {
    try {
      if (ids.length === 0) {
        return { success: true, count: 0 }
      }

      const realm = getDatabase()
      let deletedCount = 0

      realm.write(() => {
        for (const id of ids) {
          const objectId = new Realm.BSON.ObjectId(id)
          const record = realm.objectForPrimaryKey('BrowsingHistory', objectId)
          if (record) {
            realm.delete(record)
            deletedCount++
          }
        }
      })

      console.log(`✅ 批量删除浏览记录成功，删除了 ${deletedCount} 条记录`)

      return {
        success: true,
        count: deletedCount
      }
    } catch (error) {
      console.error('❌ 批量删除浏览记录失败:', error)
      return {
        success: false,
        error: `批量删除浏览记录失败: ${error}`
      }
    }
  }

  /**
   * 通过兼容数值ID查找记录
   */
  async findByLegacyId(id: number): Promise<DatabaseResult<BrowsingHistoryModel | null>> {
    try {
      const realm = getDatabase()
      const record = realm.objects('BrowsingHistory').filtered('id == $0', id)[0] as unknown as
        | BrowsingHistoryModel
        | undefined
      return { success: true, data: record ?? null }
    } catch (error) {
      console.error('❌ 根据数值ID查找浏览记录失败:', error)
      return { success: false, error: `根据数值ID查找浏览记录失败: ${error}` }
    }
  }

  /**
   * 通过兼容数值ID更新记录
   */
  async updateRecordByLegacyId(
    id: number,
    input: Omit<UpdateBrowsingHistoryInput, 'id'>
  ): Promise<DatabaseResult<BrowsingHistoryModel>> {
    try {
      const realm = getDatabase()
      const record = realm.objects('BrowsingHistory').filtered('id == $0', id)[0] as unknown as
        | BrowsingHistoryModel
        | undefined
      if (!record) return { success: false, error: '记录不存在' }

      realm.write(() => {
        if (input.title !== undefined) record.title = input.title
        if (input.favicon_url !== undefined) record.favicon_url = input.favicon_url
        if (input.visit_time !== undefined) record.visit_time = input.visit_time
        if (input.visit_count !== undefined) record.visit_count = input.visit_count
        record.updated_at = new Date()
      })

      return { success: true, data: record }
    } catch (error) {
      console.error('❌ 通过数值ID更新浏览记录失败:', error)
      return { success: false, error: `通过数值ID更新浏览记录失败: ${error}` }
    }
  }

  /**
   * 通过兼容数值ID删除记录
   */
  async deleteRecordByLegacyId(id: number): Promise<DatabaseResult<void>> {
    try {
      const realm = getDatabase()
      const rec = realm.objects('BrowsingHistory').filtered('id == $0', id)[0] as unknown as
        | BrowsingHistoryModel
        | undefined
      if (!rec) return { success: false, error: '记录不存在' }
      realm.write(() => {
        realm.delete(rec)
      })
      return { success: true }
    } catch (error) {
      console.error('❌ 通过数值ID删除浏览记录失败:', error)
      return { success: false, error: `通过数值ID删除浏览记录失败: ${error}` }
    }
  }

  /**
   * 通过兼容数值ID批量删除
   */
  async deleteRecordsByLegacyIds(ids: number[]): Promise<DatabaseResult<void>> {
    try {
      const realm = getDatabase()
      let deleted = 0
      realm.write(() => {
        for (const id of ids) {
          const rec = realm.objects('BrowsingHistory').filtered('id == $0', id)[0] as unknown as
            | BrowsingHistoryModel
            | undefined
          if (rec) {
            realm.delete(rec)
            deleted++
          }
        }
      })
      return { success: true, count: deleted }
    } catch (error) {
      console.error('❌ 通过数值ID批量删除浏览记录失败:', error)
      return { success: false, error: `通过数值ID批量删除浏览记录失败: ${error}` }
    }
  }
}
